Skip to content

CooperateISO - #1498

Open
adrianhutter wants to merge 31 commits into
Axelrod-Python:devfrom
adrianhutter:CooperateISO
Open

CooperateISO#1498
adrianhutter wants to merge 31 commits into
Axelrod-Python:devfrom
adrianhutter:CooperateISO

Conversation

@adrianhutter

@adrianhutter adrianhutter commented Aug 5, 2026

Copy link
Copy Markdown

Adding 3 strategies (LongtermTfT, ISO, CooperateISO) from https://arxiv.org/abs/2303.03519.

Made a few changes relative to the versions used in the paper. Most importantly, ISO now uses scipy.optimize instead of torch's Adam. This works equally well, is faster, and avoids having to import torch.

Ran the CooperateISO implementation from this PR against all strategies in Axelrod-4.14.0, and verified that it outperforms EvolvedLookerUp2_2_2 and DBS at both noise levels 0% and 10%.

Fix Read the Docs build failures by updating documentation requirements and conf.py:

  • Pinned sphinx to <9.0.0 and added sphinx-rtd-theme in docs/requirements.txt to ensure compatibility and prevent theme lookup errors.
  • Removed scipy from the mock modules list in docs/conf.py so that submodules like scipy.optimize can be correctly imported from the installed package during documentation generation.

@adrianhutter
adrianhutter marked this pull request as ready for review August 5, 2026 12:15

@drvinceknight drvinceknight left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really great, I enjoyed the preprint (congrats on the work)!

My requests are mainly stylistic as we tend to try and avoid inline comments (there are a number in the tests that I didn't comment on that could perhaps be moved to docstrings).

Comment thread docs/requirements.txt
@@ -1,4 +1,7 @@
sphinx>=7.0.0,<9.0.0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you help me understand why this change is needed? (This might be because of an upstream change.)

Comment thread docs/conf.py

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
on_rtd = os.environ.get("READTHEDOCS", None) == "True"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you help me understand why this change? (It might be something got stale that I'm not remembering.)

return opponent.history[-1]


# We describe memory-1 strategies as length-4 arrays, quantifying the probability of cooperation in the states [CC, CD, DC, DD].

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# We describe memory-1 strategies as length-4 arrays, quantifying the probability of cooperation in the states [CC, CD, DC, DD].

Comment on lines +87 to +114
# Apply p_noise only to own strategy, not to opponent
# (the opponent strategy already includes noise effects).
own = my_strategy + p_noise * (1.0 - 2.0 * my_strategy)

# Flip CD/DC for opponent.
opp = opp_strategy[[0, 2, 1, 3]]

# Build the transition matrix.
trans_mat = np.array(
[
own * opp,
own * (1.0 - opp),
(1.0 - own) * opp,
(1.0 - own) * (1.0 - opp),
]
).T

R, P, S, T = RPST
rewards = np.array([R, S, T, P], dtype=float)

# Don't include init state in summed rewards.
inv = np.linalg.inv(np.eye(4) - (1.0 - p_end) * trans_mat)

# Calculate expected reward,
reward = init_state @ (inv @ rewards - rewards)

# Avg. reward per step
return p_end * float(reward) / (1.0 - p_end)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove this inline comments and put the corresponding explanation in the docstring please.

Comment on lines +130 to +148
# Clamp to possible values, given noise
opp = np.clip(opponent, p_noise, 1.0 - p_noise)

# Setup initial state
init_state = np.zeros(4, dtype=np.float32)
init_state[init_state_idx] = 1.0

# Define the objective function to minimize (negative reward)
def objective(params: np.ndarray) -> float:
return -get_reward(params, opp, init_state, p_end, p_noise, RPST)

x0 = np.array([0.5, 0.5, 0.5, 0.5])
bounds = [(0.0, 1.0), (0.0, 1.0), (0.0, 1.0), (0.0, 1.0)]
result = minimize(
objective, x0, method="L-BFGS-B", bounds=bounds, options={"maxiter": 50}
)

# result.fun is the minimum loss (-reward), result.x are the optimal parameters
return -result.fun, result.x

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove the inline comments here

Comment on lines +183 to +193
# Track the opponent's rate of cooperation (numerator, denominator) for each state.
# Assume we have seen the opponent play following TfT once in each state,
# to make the opponent-model well-defined from the start.
self.ewma_CC = [1.0, 1.0]
self.ewma_CD = [1.0, 1.0]
self.ewma_DC = [0.0, 1.0]
self.ewma_DD = [0.0, 1.0]

# Initial cooperation probabilities (num / den)
self.opp_model = [1.0, 0.0, 1.0, 0.0]
self.my_policy = [1.0, 0.0, 1.0, 0.0]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move these inline comments to the docstring of the __init__

Comment on lines +300 to +301
# Estimate of the opponent's rate of playing D after C, taking noise
# into account.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Estimate of the opponent's rate of playing D after C, taking noise
# into account.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants